home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 2 / United Public Domain Gold 2.iso / utilities / pu295.dms / pu295.adf / Logging / IARULog / IARULOG.BAS < prev    next >
BASIC Source File  |  1988-12-21  |  15KB  |  443 lines

  1. ' IARULOG.BAS version 1.2
  2. ' Amiga Version by John Gager-K7KB
  3. ' Copyright (© 1986,1987 by Clarke Greene K1JX)  NOT FOR COMMERCIAL USE
  4. '
  5. ' This Microsoft (tm) BASIC program will build a complete log package
  6. ' for the IARU HF Championship.
  7. '
  8. ' The file containing the log entries must be an ASCII file in the
  9. ' following format:
  10. '               (each band requires a separate log entry file)
  11. '
  12. ' TIME       CALLSIGN        RCV'D REPORT  (each log entry must be
  13. '                                          followed by a carriage return)
  14. '
  15. ' At least one space must be between each field of each log entry. Only
  16. ' a changed digit in the time field must be present; for example, if the
  17. ' contest begins at 1800Z and the first contact is made at 1802Z and the
  18. ' second contact is made at 1805Z, then only 5 need be entered in the
  19. ' time field. If the third contact is made at 1812Z, then 12 should be
  20. ' entered in the time field. If the next contact is made at 1812Z, then
  21. ' no number need be entered in the time field (however, be sure to enter
  22. ' a space to indicate separation between fields).
  23. '
  24. ' These files will be produced:
  25. '
  26. ' <filename>.LOG - this is a complete log ready for printing
  27. ' <filename>.DUP - this is a sorted duplicate listing ready for printing
  28. ' <filename>.SUM - this is a summary sheet ready for printing
  29. '
  30. '
  31. ' Depending on the version of BASIC for your particular machine, the CLS
  32. ' (Clear Screen) command must be changed. Consult your own computer's
  33. ' BASIC documentation for more information.
  34. '
  35. '
  36. ' If compiling (a VERY good idea for several orders of magnitude
  37. ' improvement in speed), use O and E switches. 
  38. '
  39. ' This program also uses a prefix library file (DXPREFIX.LIB), which MUST
  40. ' be on the same disc (and in the same subdirectory) as this program.
  41. '
  42. ' Define arrays and variables
  43. '
  44. CLEAR ,70000&:DEFINT A-Z : OPTION BASE 1
  45. DIM ENTRY$(1500), MULT$(100), PFX$(1000), CNT$(1000), WIERDPFX$(50), WIERDCNT$(50), Q(100)
  46. BLANK$=" " : BL$="" : SLANT$="/" : TRUE=-1
  47. DUPE$="- Duplicate QSO -" : NEWZONE$="    Mult. #"
  48. CONTINENTS$="AFASEUNAOCSA"
  49. '
  50. ' Define format strings for printouts
  51. '
  52. LOGFORM$="   \      \  \  \   \           \    \   \    \        \ #   \                \"
  53. DUPFORM$="      \         \   \          \   \          \   \          \   \          \"
  54. SUMFORM$="     \         \    \         \    \         \    \         \    \         \"
  55. '
  56. CLS
  57. COLOR 3 : PRINT : PRINT TAB(24) "IARU HF Competition Log Processor" : COLOR 1 : PRINT
  58. '
  59. '  Read prefix table file
  60. '
  61. PRINT TAB(5)  "Reading prefix library...";
  62. I=0 ' initialize array subscript
  63. OPEN ":DXPREFIX.LIB" FOR INPUT AS #1
  64. WHILE NOT EOF(1)
  65.   I=I+1
  66.   INPUT #1, PFX$(I), DUMMY$, DUMMY$, CNT$(I) ' DUMMY$ is a dummy variable
  67.                                              ' for unused data
  68. WEND
  69. CLOSE
  70. TABLESIZE=I ' prefix table length
  71. COLOR 3 : PRINT "Done" : COLOR 1
  72. '
  73. '  Get user input
  74. '
  75. PRINT : PRINT TAB(5) "What is the station callsign? ";
  76. INPUT "", MYCALL$:MYCALL$=UCASE$(MYCALL$)
  77. THISENTRY$=MYCALL$ : IF INSTR(THISENTRY$,SLANT$)>0 THEN GOSUB GetPortPrefix ELSE THISPFX$=LEFT$(THISENTRY$,4)
  78. GOSUB SearchPrefix : IF NOT INLIST THEN GOSUB SearchWierd
  79.                      ' If the prefix can't be found
  80.                      ' in table, look elsewhere.
  81. MYCNT$=THISCNT$
  82.  
  83. GetZone:
  84.  
  85. PRINT : PRINT TAB(5) "What is the station's zone? ";
  86. INPUT "", MYZONE$
  87. IF VAL(MYZONE$)>=1 AND VAL(MYZONE$)<=75 GOTO GoodZone
  88. PRINT CHR$(7) : PRINT TAB(8) "Is '"; MYZONE$; "' correct? <Y/N>  ";
  89. INPUT "", ANS$ : IF UCASE$(ANS$)<>"Y" GOTO GetZone
  90.  
  91. GoodZone:
  92.  
  93. IF VAL(MYZONE$)<10 AND LEN(MYZONE$)=1 THEN MYZONE$="0"+MYZONE$
  94. PRINT : PRINT TAB(5) "What is the beginning date of the contest";
  95. COLOR 3 : PRINT" <DD/MM/YR>: "; : COLOR 1
  96. INPUT "", STARTDATE$
  97. MARK=INSTR(STARTDATE$,"/") : IF MARK=0 THEN MARK=INSTR(STARTDATE$,"-")
  98. STARTDAY=VAL(LEFT$(STARTDATE$,MARK-1))
  99. STARTDATE$=RIGHT$(STARTDATE$,LEN(STARTDATE$)-MARK)
  100. MARK=INSTR(STARTDATE$,"/") : IF MARK=0 THEN MARK=INSTR(STARTDATE$,"-")
  101. MON$=" July  "
  102. YR$=RIGHT$(STARTDATE$,LEN(STARTDATE$)-MARK)
  103. PRINT : PRINT TAB(5) "What is the GMT starting time for the contest? ";
  104. INPUT "", STARTGMT$
  105.  
  106. GetLog:
  107.  
  108. PRINT : PRINT TAB(5) "What file is the log extract located in? ";
  109. INPUT "", INFILE$ : GOSUB CheckForFile ' check to see if file is valid
  110. IF INSTR(INFILE$,".")<>0 THEN OUTFILE$=LEFT$(INFILE$,INSTR(INFILE$,".")-1) ELSE OUTFILE$=INFILE$
  111. PRINT : PRINT TAB(5) "What frequency band is the log extract for? ";
  112. INPUT "", BAND$
  113. PRINT : PRINT TAB(5) "Which mode is the log extract for?"
  114. PRINT TAB(5) "[Type 1 for CW or 2 for Phone] : ";
  115. INPUT "", MODE
  116. IF MODE=1 THEN RST$="599" ELSE RST$="59"
  117. SENT$=RST$+MYZONE$
  118. '
  119. '  Build log file
  120. '
  121. CLS
  122. PRINT : PRINT TAB(5) "Duping and counting...";
  123. '
  124. '  Clear arrays
  125. '
  126. FOR I=1 TO 1500
  127.   ENTRY$(I)=BL$
  128. NEXT I
  129. FOR I=1 TO 100
  130.   MULT$(I)=BL$
  131.   Q(I)=1
  132. NEXT I
  133. '
  134. '  Initialize variables
  135. '
  136. RAWTOTAL=0 : QSOS=0 : DUPES=0 : MULTNR=0 : TOTPOINTS=0
  137. DAY=STARTDAY : PREVIOUSGMT$=STARTGMT$
  138. '
  139. '  Open input file and ouput .LOG file
  140. '
  141. OPEN INFILE$ FOR INPUT AS #1 LEN=5000
  142. OPEN OUTFILE$+".LOG" FOR OUTPUT AS #2 LEN=5000
  143. '
  144. '  Input data, process, and enter into output file
  145. '
  146. WHILE NOT EOF(1)
  147.   LINE INPUT #1, THISENTRY$ ' read entire line from disc file
  148.   IF LEN(THISENTRY$)=0 THEN GOTO SkipEntry
  149.   WHILE ASC(RIGHT$(THISENTRY$,1))<48 AND LEN(THISENTRY$)>0
  150.     THISENTRY$=LEFT$(THISENTRY$,LEN(THISENTRY$)-1) ' Strip off trailing
  151.                                                    ' spaces, etc.
  152.   WEND
  153.   IF LEN(THISENTRY$)>0 THEN RAWTOTAL=RAWTOTAL+1 ELSE GOTO SkipEntry
  154. '
  155. '  Separate received report from THISENTRY$
  156. '
  157.   RCVD$=BL$ ' initialize rcvd field to blank
  158.   WHILE ASC(RIGHT$(THISENTRY$,1))>=48
  159.     RCVD$=RIGHT$(THISENTRY$,1)+RCVD$
  160.     THISENTRY$=LEFT$(THISENTRY$,LEN(THISENTRY$)-1)
  161.   WEND
  162.   IF LEN(RCVD$)<(LEN(RST$)+2) OR ASC(RCVD$)>=65 THEN RCVD$=RST$+RCVD$
  163.   WHILE ASC(RIGHT$(THISENTRY$,1))<48
  164.     THISENTRY$=LEFT$(THISENTRY$,LEN(THISENTRY$)-1) ' Strip off trailing
  165.                                                    ' spaces, etc.
  166.   WEND
  167. '
  168. '  Separate GMT from THISENTRY$
  169. '
  170.   WHILE ASC(LEFT$(THISENTRY$,1))<48
  171.     THISENTRY$=RIGHT$(THISENTRY$,LEN(THISENTRY$)-1) ' Strip off leading
  172.                                                     ' spaces.
  173.   WEND
  174.   IF INSTR(THISENTRY$,BLANK$)<>0 THEN GMT$=LEFT$(THISENTRY$,INSTR(THISENTRY$,BLANK$)-1) ELSE GMT$=BL$
  175.   THISENTRY$=RIGHT$(THISENTRY$,(LEN(THISENTRY$)-LEN(GMT$)))
  176.   WHILE LEFT$(THISENTRY$,1)=BLANK$
  177.     THISENTRY$=RIGHT$(THISENTRY$,LEN(THISENTRY$)-1) ' Strip off leading
  178.                                                     ' spaces.
  179.   WEND
  180. '
  181. '  Fill in missing time data
  182.   GMT$=LEFT$(PREVIOUSGMT$,(4-LEN(GMT$)))+GMT$
  183.   THEDATE$=BL$ : IF GMT$<PREVIOUSGMT$ THEN DAY=DAY+1 : THEDATE$=STR$(DAY)+MON$
  184. '
  185. '  Check for dupes
  186. '
  187.   THISENTRY$=UCASE$(THISENTRY$)
  188.   DUPE.QSO=NOT TRUE : NOTE$=BL$ ' blank note
  189.   FOR I=1 TO QSOS
  190.     IF LEN(ENTRY$(I))<>LEN(THISENTRY$) GOTO NotDupe
  191.     IF ENTRY$(I)=THISENTRY$ THEN NOTE$=DUPE$ : DUPES=DUPES+1 : POINTS=0 : DUPE.QSO=TRUE : I=QSOS
  192.   NotDupe: NEXT I
  193.   IF DUPE.QSO GOTO WriteEntry ' Skip over prefix search if
  194.                               ' this entry is a dupe.
  195.   QSOS=QSOS+1 : ENTRY$(QSOS)=THISENTRY$
  196. '
  197. '  Determine "zone" and search through multiplier table
  198. '
  199.   THISZONE$=RIGHT$(RCVD$,LEN(RCVD$)-LEN(RST$))
  200.   NEWMULT=TRUE ' initially call contact a new multiplier
  201.   FOR I=1 TO MULTNR
  202.     IF MULT$(I)=THISZONE$ THEN Q(I)=Q(I)+1 : NEWMULT=NOT TRUE : I=MULTNR
  203.   NEXT I
  204.   IF NEWMULT THEN MULTNR=MULTNR+1 : MULT$(MULTNR)=THISZONE$ : NOTE$=NEWZONE$+STR$(MULTNR)
  205.   IF ASC(THISZONE$)>=65 OR THISZONE$=MYZONE$ THEN POINTS=1 : GOTO Totals
  206. '
  207. '  Determine prefix and search prefix library for contact continent
  208. '
  209. IF INSTR(THISENTRY$,SLANT$)>0 THEN GOSUB GetPortPrefix ELSE THISPFX$=LEFT$(THISENTRY$,4)
  210. GOSUB SearchPrefix : IF NOT INLIST THEN GOSUB SearchWierd
  211.                      ' If the prefix can't be found
  212.                      ' in table, look elsewhere.
  213. '
  214. '  Resolve USA prefix ambiguities (i.e. KG6=Guam vs. KG6=Calif.) and
  215. '  calculate points.
  216. '
  217.   IF LEFT$(THISPFX$,1)="K" AND (VAL(THISZONE$)=6 OR VAL(THISMULT$)=7 OR VAL(THISMULT$)=8) THEN THISCNT$="NA"
  218.   IF THISCNT$=MYCNT$ THEN POINTS=3 ELSE POINTS=5
  219. '
  220. '  Total QSO points
  221. '
  222. Totals:
  223.  
  224.   TOTPOINTS=TOTPOINTS+POINTS
  225. '
  226. '  Write entry to file
  227. '
  228. WriteEntry:
  229.   
  230.   IF (RAWTOTAL-1) MOD 50=0 THEN GOSUB PrintHeader ' Print header if this
  231.                                                   ' is the beginning of
  232.                                                   ' a page.
  233.   PRINT #2, USING LOGFORM$; THEDATE$; GMT$; THISENTRY$; SENT$; RCVD$; POINTS; NOTE$
  234.   IF RAWTOTAL MOD 50=0 THEN PRINT #2, CHR$(12) ' Print a form feed if
  235.                                                ' this is the end of page.
  236.   PREVIOUSGMT$=GMT$ : GMT$=BL$
  237.   
  238. SkipEntry:
  239. WEND
  240.  
  241. IF RAWTOTAL MOD 50<>0 THEN PRINT #2, CHR$(12) ' If a form feed hasn't
  242.                                               ' been printed, then print
  243.                                               ' one now.
  244. CLOSE
  245. COLOR 3 : PRINT "Done" : COLOR 1
  246. '
  247. '  Build dupe sheet
  248. '
  249. PRINT : PRINT TAB(5) "Preparing dupe sheet...";
  250. '
  251. '  Sort callsigns for dupe sheet
  252. '
  253. M=QSOS\2
  254. WHILE M>0
  255.   FOR I=M+1 TO QSOS
  256.     J=I-M
  257.     WHILE J>0
  258.       IF ENTRY$(J)>ENTRY$(J+M) THEN SWAP ENTRY$(J),ENTRY$(J+M) : J=J-M ELSE J=0
  259.     WEND
  260.   NEXT I
  261.   M=M\2
  262. WEND
  263. '
  264. '  Enter dupe sheet into file
  265. '
  266. OPEN OUTFILE$+".DUP" FOR OUTPUT AS #1
  267. IF QSOS MOD 250=0 THEN LASTPAGE=QSOS\250 ELSE LASTPAGE=QSOS\250+1
  268. FOR PAGE=1 TO LASTPAGE
  269.   PRINT #1, SPC(20-(LEN(MYCALL$)+LEN(BAND$))/2); MYCALL$; " -- Dupe Sheet for ";
  270.   PRINT #1, BAND$; " MHz Band -- Page"; STR$(PAGE)
  271.   PRINT #1, BL$ : PRINT #1, BL$
  272.   FOR ROW=1 TO 50
  273.     E=(PAGE-1)*250+ROW
  274.     PRINT #1, USING DUPFORM$; ENTRY$(E); ENTRY$(E+50); ENTRY$(E+100); ENTRY$(E+150); ENTRY$(E+200)
  275.   NEXT ROW
  276.   PRINT #1, CHR$(12) ' go to next page
  277. NEXT PAGE
  278. CLOSE
  279. COLOR 3 : PRINT "Done" : COLOR 1
  280. '
  281. '  Build summary listing
  282. '
  283. PRINT : PRINT TAB(5) "Preparing summary sheet...";
  284. '
  285. '  Sort multipliers for summary sheet
  286. '
  287. M=MULTNR\2
  288. WHILE M>0
  289.   FOR I=M+1 TO MULTNR
  290.     J=I-M
  291.     WHILE J>0
  292.       IF MULT$(J)>MULT$(J+M) THEN SWAP MULT$(J),MULT$(J+M) : SWAP Q(J),Q(J+M) : J=J-M ELSE J=0
  293.     WEND
  294.   NEXT I
  295.   M=M\2
  296. WEND
  297. '
  298. '  Append number of qsos per zone onto zone numbers
  299. '
  300. FOR I=1 TO MULTNR
  301.   MULT$(I)=MULT$(I)+SPACE$(6-LEN(MULT$(I)))+" -"+STR$(Q(I))
  302. NEXT I
  303. '
  304. '  Enter summary sheet into file
  305. '
  306. OPEN OUTFILE$+".SUM" FOR OUTPUT AS #1
  307. PRINT #1, SPC(8-(LEN(MYCALL$)+LEN(BAND$))/2); MYCALL$; " -- Summary Sheet for "; BAND$;
  308. PRINT #1, " MHz Band - "; YR$; " IARU HF Championship" 
  309. PRINT #1, BL$
  310. PRINT #1, TAB(11); "Multiplier Listing and number of contacts per multiplier"
  311. PRINT #1, BL$ : PRINT #1, BL$
  312. IF MULTNR MOD 5=0 THEN LASTROW=MULTNR\5 ELSE LASTROW=MULTNR\5+1
  313. FOR ROW=1 TO LASTROW
  314.   PRINT #1, USING SUMFORM$; MULT$(ROW); MULT$(ROW+LASTROW); MULT$(ROW+LASTROW*2); MULT$(ROW+LASTROW*3); MULT$(ROW+LASTROW*4)
  315. NEXT ROW
  316. PRINT #1, BL$ : PRINT #1, BL$ : PRINT #1, BL$
  317. PRINT #1, TAB(17); "Total Valid QSOs - "; STR$(QSOS); TAB(45); "Dupes - "; STR$(DUPES)
  318. PRINT #1, TAB(17); "Total QSO points - "; STR$(TOTPOINTS)
  319. PRINT #1, TAB(17); "Multipliers - "; STR$(MULTNR)
  320. CLOSE
  321. COLOR 3 : PRINT "Done" : COLOR 1
  322. '
  323. '  Print results
  324. '
  325. CLS : PRINT CHR$(7)
  326. PRINT : PRINT TAB(5) "Results for the "; BAND$; " MHz band":PRINT 
  327. PRINT TAB(8) "Valid QSOs:"; : COLOR 3 : PRINT USING"          ####";QSOS : COLOR 1
  328. PRINT TAB(8) "Duplicate QSOs:"; : COLOR 3 : PRINT USING"        ##";DUPES : COLOR 1
  329. PRINT TAB(8) "Total QSO points:"; : COLOR 3 : PRINT USING" ######,";TOTPOINTS : COLOR 1
  330. PRINT TAB(8) "Multipliers:"; : COLOR 3 : PRINT USING"          ###";MULTNR : COLOR 1
  331. PRINT : PRINT : PRINT 
  332. PRINT TAB(5) "Type "; : COLOR 3 :PRINT "C"; : COLOR 1
  333. PRINT" to continue with another band,"
  334. PRINT TAB(5) "or any other key to Exit ";
  335. ANS$=INPUT$(1)
  336. IF UCASE$(ANS$)="C" THEN CLS : GOTO GetLog ELSE CLS : END
  337. '
  338. '  Subroutine to trap missing file
  339. '
  340. CheckForFile:
  341.  
  342. ON ERROR GOTO NoFile:
  343. OPEN INFILE$ FOR INPUT AS #1 ' try opening file
  344. ON ERROR GOTO 0
  345. CLOSE
  346. RETURN
  347.  
  348. NoFile:
  349.  
  350. PRINT CHR$(7) : PRINT TAB(4) "That file does not exist - type X to Exit or any other key to continue ";
  351. ANS$=INPUT$(1) : IF UCASE$(ANS$)="X" THEN CLS : END
  352. PRINT 
  353. RESUME GetLog
  354. '
  355. '  Subroutine to determine prefix from portable designator
  356. '
  357. GetPortPrefix:
  358.  
  359. MARK=INSTR(THISENTRY$,SLANT$)
  360. IF MARK>3 THEN THISPFX$=RIGHT$(THISENTRY$,LEN(THISENTRY$)-MARK) ELSE THISPFX$=LEFT$(THISENTRY$,MARK-1)
  361. IF LEN(THISPFX$)>1 GOTO ReturnPfx ' have prefix - return
  362. IF ASC(THISPFX$)>58 OR ASC(THISPFX$)<47 THEN THISPFX$=LEFT$(THISENTRY$,4) : GOTO ReturnPfx
  363. K=2 ' find position of first numeral in call
  364. WHILE (ASC(MID$(THISENTRY$,K,1))>57 OR ASC(MID$(THISENTRY$,K,1))<48) AND K<LEN(THISENTRY$)
  365.   K=K+1
  366. WEND
  367. THISPFX$=LEFT$(THISENTRY$,K-1)+THISPFX$ ' new prefix = portable number
  368.                                         ' in old prefix
  369. ReturnPfx:
  370. RETURN
  371. '
  372. '  Subroutine to determine station's continent from prefix
  373. '
  374. SearchPrefix:
  375.  
  376. K=4 : INLIST=NOT TRUE : SAVEDPFX$=THISPFX$
  377. WHILE K>0 AND INLIST=NOT TRUE
  378.   THISPFX$=LEFT$(THISPFX$,K)
  379.   LOW=1 : HIGH=TABLESIZE : INLIST=NOT TRUE ' Initial values for 
  380.                                            ' binary sort.
  381.   WHILE LOW<=HIGH AND INLIST=NOT TRUE
  382.     L=(LOW+HIGH)\2
  383.     IF THISPFX$=PFX$(L) THEN INLIST=TRUE : THISCNT$=CNT$(L)
  384.     IF THISPFX$<PFX$(L) THEN HIGH=L-1 ELSE LOW=L+1
  385.   WEND
  386.   K=K-1
  387. WEND
  388. RETURN
  389. '
  390. '  Subroutine to search unusual prefix list
  391. '
  392. SearchWierd:
  393.  
  394. IF NRWIERDPFX=0 GOTO GetPrefix ' If the supplementary prefix list is
  395.                                ' empty, then skip ahead.
  396. K=4
  397. WHILE K>0
  398.   SAVEDPFX$=LEFT$(SAVEDPFX$,K)
  399.   FOR J=1 TO NRWIERDPFX
  400.     IF SAVEDPFX$=WIERDPFX$(J) THEN INLIST=TRUE : THISCNT$=WIERDCNT$(J) : J=NRWIERDPFX : K=1
  401.   NEXT J
  402.   K=K-1
  403. WEND
  404. IF INLIST THEN RETURN ' If the prefix was found, then return.
  405. '
  406. '  Routine to get prefix definition and continent
  407. '  from user for prefix not found in library.
  408. '
  409. GetPrefix:
  410.  
  411. CLS:PRINT CHR$(7) : PRINT
  412. PRINT TAB(5) "The prefix for "; : COLOR 3 : PRINT THISENTRY$;
  413. COLOR 1 : PRINT" can't be found in the prefix library."
  414. PRINT : PRINT TAB(5) "What is the callsign prefix? "; 
  415. INPUT "", THISPFX$ : THISPFX$=UCASE$(THISPFX$)
  416. NRWIERDPFX=NRWIERDPFX+1 : WIERDPFX$(NRWIERDPFX)=THISPFX$
  417.  
  418. GetContinent:
  419.  
  420. PRINT : PRINT TAB(5) "What is the continent? [AF, AS, EU, NA, OC, SA] ";
  421. INPUT "", THISCNT$ : THISCNT$=UCASE$(THISCNT$)
  422. FOR J=1 TO 11 STEP 2
  423.   IF THISCNT$=MID$(CONTINENTS$,J,2) THEN INLIST=TRUE : J=11
  424. NEXT J ' Check for valid continent name
  425. IF NOT INLIST THEN PRINT CHR$(7);: GOTO GetContinent
  426. WIERDCNT$(NRWIERDPFX)=THISCNT$
  427. CLS : PRINT : PRINT TAB(5) "Back to duping and counting...";
  428. RETURN
  429. '
  430. '  Subroutine to print log sheet header
  431. '
  432. PrintHeader:
  433.  
  434. PRINT #2, BL$
  435. PRINT #2, TAB(5); MYCALL$; "  "; BAND$; " MHz Log"; TAB(70); "Page"; STR$(RAWTOTAL\50+1)
  436. PRINT #2, BL$
  437. PRINT #2, "     Date    Time   Callsign         Sent     Rcvd      Pt.        Notes"
  438. PRINT #2, "   "; STRING$(74,61)
  439. THEDATE$=STR$(DAY)+MON$
  440. RETURN 
  441.